#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define rep(i, l, r) for (int i = l; i <= r; ++i)
const int N = 4e5 + 5;
const int base = 131; 
const int P1 = 1e9 + 9, P2 = 1e9 + 7; 
struct Graph {
  struct edge { int v, id; } ;
  vector <edge> G[N]; int cnt, num, sz[N], cir[N];
  pair <int, int> hax[N];
  pair <int, pair <int, int>> a[N];   
  void add (int u, int v, int id) {
    G[u].push_back((edge){v, id});
    G[v].push_back((edge){u, id}); 
  }
} T[2];
pair <pair <int, int>, int> tmp[N]; 
int n, u, v, tp, cnt, pw1[N], pw2[N], st[N], dep[N], vis[N], book[N]; 

int inc (int a, int b, int P) { return (a += b) >= P ? a - P : a; }
int dec (int a, int b, int P) { return (a -= b) < 0 ? a + P : a; }
int mul (int a, int b, int P) { return 1ll * a * b % P; }
int fpow (int a, int b, int P) { int ans = 1; for ( ; b; a = mul(a, a, P), b >>= 1) if(b & 1) ans = mul(ans, a, P); return ans; }

int main () {
  ios :: sync_with_stdio(0), cin.tie(0), cout.tie(0); 
  cin >> n; 
  pw1[0] = pw2[0] = 1; 
  rep(i, 1, max(n, 10)) {
    pw1[i] = mul(pw1[i - 1], base, P1); 
    pw2[i] = mul(pw2[i - 1], base, P2); 
  }
  rep(i, 1, n) cin >> u >> v, T[0].add(u, v, i); 
  rep(i, 1, n) cin >> u >> v, T[1].add(u, v, i); 
  function <void(int, int, int)> dfs1 = [&](int o, int u, int f) {
    vis[u] = 1, st[++tp] = u, dep[u] = dep[f] + 1; 
    for (auto e : T[o].G[u]) if(!book[e.id]) {
      book[e.id] = 1; 
      if(!vis[e.v]) dfs1(o, e.v, u); 
      else if(dep[e.v] < dep[u]) {
        for ( ; st[tp] != e.v; --tp) T[o].cir[st[tp]] = 1; 
        T[o].cir[st[tp]] = 1;  
      }
    }
    --tp; 
  } ;
  dfs1(0, 1, 0); 
  memset(vis, 0, sizeof(vis));
  memset(book, 0, sizeof(book)); 
  tp = 0, dfs1(1, 1, 0); 
  rep(i, 1, n) rep(j, 0, 1) T[j].cnt += T[j].cir[i]; 
  if(T[0].cnt != T[1].cnt) { puts("No"); return 0; }
  function <void(int, int, int)> dfs2 = [&](int o, int u, int f) {
    T[o].sz[u] = 1, dep[u] = dep[f] + 1; 
    for (auto e : T[o].G[u]) if(!T[o].cir[e.v] && e.v != f) 
      dfs2(o, e.v, u); 
    cnt = 0; 
    for (auto e : T[o].G[u]) if(!T[o].cir[e.v] && e.v != f) 
      tmp[++cnt] = make_pair(T[o].hax[e.v], e.v); 
    sort(tmp + 1, tmp + cnt + 1); 
    rep(i, 1, cnt) {
      T[o].sz[u] += T[o].sz[tmp[i].second]; 
      T[o].hax[u].first = inc(tmp[i].first.first, 
        mul(T[o].hax[u].first, pw1[T[o].sz[u]], P1), P1);
      T[o].hax[u].second = inc(tmp[i].first.second, 
        mul(T[o].hax[u].second, pw2[T[o].sz[u]], P2), P2);
    }
    T[o].hax[u].first = inc(pw1[2], inc(mul(T[o].hax[u].first, pw1[1], P1), 2, P1), P1);
    T[o].hax[u].second = inc(pw2[2], inc(mul(T[o].hax[u].second, pw2[1], P2), 2, P2), P2);
  } ;
  rep(o, 0, 1) rep(i, 1, n) if(T[o].cir[i]) {
    dfs2(o, i, 0), T[o].a[++T[o].num].second = T[o].hax[i]; 
    T[o].a[T[o].num].first = T[o].sz[i]; 
  }
  rep(o, 0, 1) sort(T[o].a + 1, T[o].a + T[o].cnt + 1); 
  rep(i, 1, T[0].cnt) if(T[0].a[i] != T[1].a[i]) { 
    puts("No"); return 0;
  }
  puts("Yes"); 
  return 0; 
}
